import { _decorator, color, director, System, assetManager } from 'cc';
import { BaseManager } from './../libs/rxjs/cc3/BaseManager';
import { LoadingPanelMode } from './Enums';
import { GameKey, SubgameConfig } from './SubgameConfig';
import { am } from './AudioManager';
import { SubgameManager } from './SubgameManager';
import { uim } from '../libs/ui/UIManager';
import { ReactiveProperty } from './../libs/rxjs/cc3/ReactiveProperty';
import { ReactiveCommand } from '../libs/rxjs/cc3/ReactiveCommand';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
class GameManager extends BaseManager {

    public static instance: GameManager;
    static ID = 'game_system';
    get logColorOverride() { return color().fromHEX('#EEDDCC') };

    static registerSystem() {
        director.unregisterSystem(director.getSystem(GameManager.ID));
        director.registerSystem(GameManager.ID, gm, System.Priority.MEDIUM);
        gm.init();
    }

    loadingPanelMode = LoadingPanelMode.FirstTime;
    maxProgressValue = 100;
    curProgressValue = ReactiveProperty.Create(0);
    curProgressValue2 = ReactiveProperty.Create(0);

    loadingAssets = ReactiveProperty.Create(true);
    wsConnected = ReactiveProperty.Create(false);

    curSubgame = ReactiveProperty.Create<GameKey>(null);
    enterGameCommand = ReactiveCommand.Create<GameKey>();
    leaveGameCommand = ReactiveCommand.Create<GameKey>();

    subgameManagers: Record<GameKey, SubgameManager> = {} as Record<GameKey, SubgameManager>;

    useObserves() {
        return [
            this.enterGameCommand.subscribe(this.enterGame.bind(this)),
            this.leaveGameCommand.subscribe(this.leaveGame.bind(this))
        ];
    }

    enterGame(subgameKey: GameKey) {
        this.log('enterGame', subgameKey);
        let config = SubgameConfig[subgameKey];
        this.loadingPanelMode = LoadingPanelMode.Default;
        this.curProgressValue.value = 0;
        this.curProgressValue2.value = 0;
        this.loadingAssets.value = true;
        assetManager.loadBundle(config.assetbundleName, (err, bundle) => {
            if (err) {
                this.log('loadBundle err', err);
                return;
            }
            this.log('loadBundle success', bundle);
            globalThis[config.manager].registerSystem();
            this.curSubgame.value = subgameKey;
            uim.standby.whenTrueOnce().subscribe(_ => {
                this.subgameManagers[subgameKey].onEnterGame(subgameKey).subscribe({
                    complete: () => {
                        this.loadingAssets.value = false;
                    }
                });
            });
        });
    }

    leaveGame(subgameKey: GameKey) {
        this.log('leaveGame', subgameKey);
        let config = SubgameConfig[subgameKey];
        this.subgameManagers[subgameKey].onLeaveGame();
        globalThis[config.manager].unregisterSystem();
        this.curSubgame.value = GameKey.lobby;
        uim.standby.whenTrueOnce().subscribe(_ => {
            let bundle = assetManager.getBundle(config.assetbundleName);
            bundle.releaseAll();
            assetManager.removeBundle(bundle);
            this.log('release bundle', config.assetbundleName);
        });
    }

}

globalThis.GameManager = GameManager;

export const gm = GameManager.instance = new GameManager();
